package com.example.myfirstgame.model;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;

import com.example.myfirstgame.R;
import com.example.myfirstgame.controller.GameObject;
import com.example.myfirstgame.helper.Coordinate;
import com.example.myfirstgame.helper.DataInstance;
import com.example.myfirstgame.helper.RasterPoint;

public class TrafficLight implements GameObject {

	// ==================
	// FIELDS
	// ==================
	// integer
	public static final int RED = 0;
	public static final int YELLOW = RED + 1;
	public static final int GREEN = YELLOW + 1;
	// unique id
	private static int counter = 0;
	private int trafficLightId = 0;
	private int trafficLightType;
	// position
	private Rect collisionRectangle = new Rect();
	private float currentX;
	private float currentY;
	private Matrix trafficLightMatrix = null;
	// trafficLight
	private long lastSystemTimeMillies;
	private static int[] lightPeriods = new int[] { 10000, 4000, 12000 };
	// Bitmap
	float mNewWidth;
	float mNewHeight;
	public static Bitmap[] trafficLightBitmap = new Bitmap[3];
	private static final float mInternalScaleFactor = 0.3f;
	private static Paint myPaint = new Paint();
	private LightStatus curLightStatus = null;
	private static Context appContext = null;
	// Final stuff
	public static final String TYPE_DEFINITION_BASE = "trafficLight";
	public static final String[] TYPE_DEFINITION = { "trafficLightRed",
			"trafficLightYellow", "trafficLightGreen" };
	public static final int TYPE_TRAFFIC_LIGHT_01 = 0x93d;
	private static final int[] RESOURCE_TRAFFIC_LIGHT = new int[] {
			R.drawable.red_light, R.drawable.yellow_light,
			R.drawable.green_light, };

	// ==================
	// CONSTRUCTOR
	// ==================

	public TrafficLight(int _trafficLightType, Context _appContext) {
		this.trafficLightType = _trafficLightType;
		this.lastSystemTimeMillies = System.currentTimeMillis();
		
		if (_appContext != null) {
			appContext = _appContext;
			setBitmaps(_trafficLightType, appContext);
			this.curLightStatus = new LightStatus(GREEN, trafficLightBitmap[GREEN]);
		}
		trafficLightId = counter;
		counter++;
	}
	
	public TrafficLight(int _trafficLightType, Context _appContext, RasterPoint pRasterPoint) {
		this.trafficLightType = _trafficLightType;
		this.lastSystemTimeMillies = System.currentTimeMillis();
		
		setPosition(pRasterPoint.getCoordinate());
		if (_appContext != null) {
			appContext = _appContext;
			setBitmaps(_trafficLightType, appContext);
			this.curLightStatus = new LightStatus(GREEN, trafficLightBitmap[GREEN]);
			scaleObject(DataInstance.getInstance().getGameObjectScalingFactor(), pRasterPoint.getRasterSize());
		}
		trafficLightId = counter;
		counter++;
	}

	// ========================
	// METHODS
	// ========================

	private static void setBitmaps(int _trafficLightType, Context appContext) {
		int[] res = new int[3];
			if (_trafficLightType == TYPE_TRAFFIC_LIGHT_01) {
				for (int i = 0; i < 3; i++) {
					res[i] = RESOURCE_TRAFFIC_LIGHT[i];
					trafficLightBitmap[i] = BitmapFactory.decodeResource(
						appContext.getResources(), res[i]);
				}
			}
	}

	private Matrix getDrawMatrix() {
		if (this.trafficLightMatrix == null) {
			this.trafficLightMatrix = new Matrix();
			float lCurrentScaleFactor = DataInstance.getInstance().getGameObjectScalingFactor() * mInternalScaleFactor; 
			this.trafficLightMatrix.postScale(lCurrentScaleFactor, lCurrentScaleFactor);
			this.trafficLightMatrix
					.postTranslate(-mNewWidth / 2, -mNewHeight / 2);
			this.trafficLightMatrix.postTranslate(currentX, currentY);
		}
		return this.trafficLightMatrix;
	}

	private LightStatus getLightStatus() {
		int status = this.curLightStatus.getCurLightStatus();
		long currentSystemMillies = System.currentTimeMillis();
		long deltaTime = currentSystemMillies - this.lastSystemTimeMillies;
		if (deltaTime >= lightPeriods[status]) {
			this.curLightStatus.setCurLightStatus((status + 1) % 3);
			this.lastSystemTimeMillies = System.currentTimeMillis();
		}
		return this.curLightStatus;
	}

	// ===============================
	// Interface Collision Object
	// ===============================

	@Override
	public String getCollisonType() {
		int status = this.curLightStatus.getCurLightStatus();
		return TYPE_DEFINITION[status];
	}

	@Override
	public Rect getBoundingRectangle() {

		int w = (int) mNewWidth;
		int h = (int) mNewHeight;

		Rect rect = new Rect((int) (currentX),
				(int) (currentY + h / 4 + h / 8), (int) (currentX + h),
				(int) (currentY + 3 * h / 4 - h / 8));
		collisionRectangle = rect;

		return collisionRectangle;
	}

	class LightStatus {

		public int curLightStatus = Integer.MAX_VALUE;
		public Bitmap curLightBitmap = null;

		public LightStatus(int curStatus, Bitmap curImage) {
			this.curLightBitmap = curImage;
			this.curLightStatus = curStatus;
		}

		public LightStatus() {
		}

		public int getCurLightStatus() {
			return curLightStatus;
		}

		public Bitmap getCurLightBitmap() {
			return curLightBitmap;
		}

		public void setCurLightStatus(int _curLightStatus) {
			this.curLightStatus = _curLightStatus;
			this.curLightBitmap = trafficLightBitmap[_curLightStatus];
		}

	}

	@Override
	public String getGameType() {
		int status = this.curLightStatus.getCurLightStatus();
		return TYPE_DEFINITION[status];
	}

	@Override
	public void draw(Canvas canvas) {
		canvas.drawBitmap(getLightStatus().getCurLightBitmap(),
				getDrawMatrix(), null);
		myPaint.setColor(Color.argb(180, 255, 0, 0));
		canvas.drawRect(this.collisionRectangle, myPaint);
	}

	@Override
	public void setPosition(Coordinate coordinate) {
		this.currentX = coordinate.getX();
		this.currentY = coordinate.getY();
	}

	@Override
	public Coordinate getPosition() {
		return new Coordinate(currentX,currentY);
	}


	@Override
	public void scaleObject(float pScaleFactor, int pRasterSize) {
		float lCurrentScaleFactor = pScaleFactor * mInternalScaleFactor;
		trafficLightMatrix = null;
		int w = trafficLightBitmap[0].getWidth();
		int h = trafficLightBitmap[0].getHeight();
		mNewHeight = h * lCurrentScaleFactor;
		mNewHeight = (float)((((int)mNewHeight)/pRasterSize)*pRasterSize);
		mNewWidth = w * lCurrentScaleFactor;
		mNewWidth = (float)((((int)mNewWidth)/pRasterSize)*pRasterSize);
	}

}
